package com.zhuyi.broadcast.service.impl;


import com.alibaba.druid.support.spring.stat.SpringStatUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.zhuyi.broadcast.mapper.ElementMapper;
import com.zhuyi.broadcast.mapper.ElementResourceRelationMapper;
import com.zhuyi.broadcast.mapper.ResourceMapper;
import com.zhuyi.broadcast.pojo.domain.AuditTask;
import com.zhuyi.broadcast.pojo.domain.Element;
import com.zhuyi.broadcast.pojo.domain.ElementResourceRelation;
import com.zhuyi.broadcast.pojo.domain.Resource;
import com.zhuyi.broadcast.service.AuditService;
import com.zhuyi.broadcast.service.ResourceService;
import com.zhuyi.common.config.ZhuYiConfig;
import com.zhuyi.common.constant.BroadcastConstants;
import com.zhuyi.common.core.domain.AjaxResult;
import com.zhuyi.common.enums.DataStatus;
import com.zhuyi.common.enums.FileCategoryEnum;
import com.zhuyi.common.utils.DateUtils;
import com.zhuyi.common.utils.SecurityUtils;
import com.zhuyi.common.utils.file.FileUploadUtils;
import com.zhuyi.common.utils.sign.Base64;
import com.zhuyi.common.utils.uuid.IdUtils;
import com.zhuyi.system.mapper.SysUserRoleMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;


import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import static com.zhuyi.common.core.domain.AjaxResult.error;

/**
 * <p>
 *  资源实现类
 * </p>
 *
 * @author dyj
 * @since 2024-12-12
 */

@Slf4j
@Service
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements ResourceService {

    @Autowired
    private ElementResourceRelationMapper elementResourceRelationMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private AuditService auditService;

    /**
     * 创建文件夹资源
     */
    @Override
    public Resource createFolderResource(Resource resource) {
        Long parentId = resource.getParentId();//parentId 是文件夹的父级文件夹ID，用来获取父文件夹的信息
        String dirName = resource.getResourceName();//资源存储名称
        Resource parentResource = null;
        if (ObjectUtils.isNotEmpty(parentId)) {
            parentResource = this.getById(parentId);//通过 parentId 获取父文件夹的资源对象 parentResource
        }
        String parentDir = ObjectUtils.isNotEmpty(parentResource) ? parentResource.getResourcePath() : "";//获取父文件夹的路径 parentDir
        String templateRootAddr = ZhuYiConfig.getUploadPath();//获取上传路径
        File parentFile = new File(templateRootAddr + "/" + parentDir);//父目录的 File 对象
        if (!parentFile.exists()) {
            parentFile.mkdir();//如果父目录不存在则调用 mkdir() 创建它
        }
        File folder = new File(parentFile.getAbsolutePath() + "/" + dirName);//创建目标文件夹 folder
        if (folder.exists()) {
            return null;//如果目标文件夹已经存在，则返回 null，表示文件夹已存在，创建失败
        }
        folder.mkdir();
        resource.setResourceCategory(FileCategoryEnum.FOLDER.getCode());//资源类型为文件夹
        resource.setFileName(dirName);//文件夹的名称 dirName
        resource.setResourcePath(parentDir + "/" + dirName);// 文件夹路径 resourcePath
        if (ObjectUtils.isNotEmpty(parentResource)) {
            String parentPath = ObjectUtils.isEmpty(parentResource.getParentIdPath()) ? "" : parentResource.getParentIdPath();//如果父文件夹存在，设置 parentIdPath
            resource.setParentIdPath(parentPath + "/" + (parentResource.getId() + ":" + parentResource.getResourceName()));
        }
        resource.setResourceState(BroadcastConstants.RESOURCE_STATE_APPROVED);//设置资源状态(默认审核中)
        resource.setUploadedBy(SecurityUtils.getLoginUser().getUser().getNickName());//设置上传用户
        resource.setResourceType("folder");
        return insertResource(resource);
    }

    /**
     * 上传资源
     */
    @Override
    public Resource uploadFileResource(MultipartFile file, Long folderId, String baseUrl,String resourceFinalName) {
        Resource resource = null;
        Resource parentResource = null; //获取父级资源信息
        if (ObjectUtils.isNotEmpty(folderId)) {
            parentResource = this.getById(folderId);
        }
        String parentPath = ObjectUtils.isNotEmpty(parentResource) ? parentResource.getResourcePath() : "";
        // 上传文件路径
        String templateRootAddr = ZhuYiConfig.getUploadPath(); // 获取根上传路径

        String resourceOriginalName = file.getOriginalFilename();  // 获取原始资源名
        String fileNameWitNoSuffix = resourceOriginalName.substring(0, resourceOriginalName.lastIndexOf("."));
        String suffixName = resourceFinalName.substring(resourceFinalName.lastIndexOf("."));  // 获取后缀名
        Date currentDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        //String dateFormatStr = sdf.format(currentDate);
        String parentDirPath = templateRootAddr + parentPath;
        //resourceOriginalName = fileNameWitNoSuffix + "_" + dateFormatStr + suffixName; // 新资源名
        resourceOriginalName = fileNameWitNoSuffix + suffixName; // 新资源名
        File dest = new File(parentDirPath  + "/" + resourceFinalName); //将文件存储路径拼接为：根目录/父级路径/文件名
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs(); //如果目标目录不存在，则调用 mkdirs() 创建
        }
        try {
            file.transferTo(dest);
            resource = new Resource();
            resource.setResourceName(resourceFinalName.substring(0,resourceFinalName.lastIndexOf(".")));
            resource.setResourceCategory(FileCategoryEnum.FILE.getCode());
            resource.setResourcePath(FileUploadUtils.getPathFileName(parentDirPath, resourceFinalName));
            resource.setFileName(resourceOriginalName);
            //resource.setFileExt(suffixName);//正常后缀
            if (!suffixName.isEmpty()) {
                resource.setResourceType(suffixName.substring(1).toUpperCase());
            }

            // 判断是否是超级管理员，是的话无需审核，不是的话需要审核
            if (sysUserRoleMapper.getRoleIdByUserId(SecurityUtils.getLoginUser().getUserId()) == 1) {
                resource.setResourceState(BroadcastConstants.RESOURCE_STATE_APPROVED);
            } else {
                resource.setResourceState(BroadcastConstants.RESOURCE_STATE_PENDING);
            }

            resource.setSize(file.getSize());//设置资源大小
            resource.setUploadTime(new Date());//设置上传时间
            resource.setParentId(folderId);
            if (ObjectUtils.isNotEmpty(parentResource)) {
                String parentIdPath = parentResource.getParentIdPath();
                resource.setParentIdPath(parentIdPath + "/" + parentResource.getId() + ":" + parentResource.getResourceName());
            }

            resource.setUploadedBy(SecurityUtils.getLoginUser().getUser().getNickName());//上传用户
            resource = this.insertResource(resource);

            //生成文件访问路径
//            String fileUrl = baseUrl + resource.getResourcePath();
//            String fileTransferServerUrl = configService.selectConfigByKey("sys_file_transfer_server");
//            if (ObjectUtils.isNotEmpty(fileTransferServerUrl)) {
//                // syncFile(fileUrl);
//                String viewKey = Base64.encode(fileUrl.getBytes());
//                resource.setViewKey(viewKey);
//                // 返回预览地址
//                String uri = fileTransferServerUrl + "/onlinePreview?url=" + viewKey;
//                resource.setFullPath(uri);
//            } else {
//                resource.setFullPath(fileUrl);
//            }
        } catch (Exception ex) {
            //异常处理
//            if (!dest.exists()) {
//                if (dest.isDirectory()) {
//                    FileUtils.deleteDirectory(dest);
//                } else {
//                    FileUtils.deleteFile(dest.getAbsolutePath());
//                }
//            }
            ex.printStackTrace();
        }

        //将资源添加到审核任务列表
        auditService.createAndSubmitAuditTask(resource, "资源");

        return resource;
    }

    /**
     * 查询资源列表
     *
     * @param resource 资源
     * @return 资源
     */
    @Transactional
    @Override
    public List<Resource> selectResourceList(Resource resource, String baseUrl)
    {
        LambdaQueryWrapper<Resource> wrapper = Wrappers.lambdaQuery(Resource.class);
        wrapper.orderBy(true, true, Resource::getResourceType);

        if (ObjectUtils.isNotEmpty(resource.getParentId())){
            wrapper.eq(Resource::getParentId, resource.getParentId());
        } else {
            wrapper.isNull(Resource::getParentId);
        }


        List<Resource> listResource = baseMapper.selectList(wrapper);
        if (ObjectUtils.isNotEmpty(listResource)) {
            for (Resource res : listResource) {
                if (res.getResourceCategory().equals((short)2)) {
                    //将资源路径 ResPath 与 baseUrl 拼接成完整的 fileUrl
                    String fileUrl = baseUrl + res.getResourcePath();

                    //将 fileUrl 转为 Base64 编码后的 viewKey
                    String viewKey = Base64.encode(fileUrl.getBytes());
                    res.setViewKey(viewKey);

                    //如果文件服务配置存在，则生成预览路径 previewUri，否则使用默认路径 fileUrl(待定预览功能)
//                    String fileTransferServerUrl = configService.selectConfigByKey("sys_file_transfer_server");
//                    if (ObjectUtils.isNotEmpty(fileTransferServerUrl)) {
//                        String previewUri = fileTransferServerUrl + "/onlinePreview?url=" + viewKey;
//                        res.setFullPath(previewUri);
//                    } else {
//                        res.setFullPath(fileUrl);
//                    }
                }

            }
        }
        return listResource;
    }

    /**
     * 查询资源预览信息
     *
     * @param id 资源主键
     * @return 资源
     */
    @Override
    public Resource selectResourceById(Long id, String baseUrl)
    {
        Resource resource = baseMapper.selectById(id);

        // 如果文件，则查询文件的转换后的图片列表
        if (ObjectUtils.isNotEmpty(resource) && resource.getResourceCategory().equals((short)2)) {
            String resourceUrl = baseUrl + resource.getResourcePath();
            String viewKey = Base64.encode(resourceUrl.getBytes());
            resource.setViewKey(viewKey);
        }
        return resource;
    }



    /**
     * 新增资源
     *
     * @param resource 资源
     * @return 结果
     */
    public Resource insertResource(Resource resource)
    {
        // 生成UUID
        long id =IdUtils.snowflakeId();
        resource.setId(id); // 设置ID

        Date date = DateUtils.getNowDate();
        resource.setUploadTime(date);//上传时间
        baseMapper.insert(resource);
        return resource;
    }

    /**
     * 删除资源信息
     *
     * @param id 资源主键
     * @return 结果
     */
    @Override
    public Boolean deleteResourceById(Long id)
    {
        //检查资源是否与元素有关联
        if(elementResourceRelationMapper.selectCount(
                new LambdaQueryWrapper<ElementResourceRelation>()
                        .eq(ElementResourceRelation::getResourceId,id))>0){
            System.out.println("该资源正在被元素使用，无法删除");
            return false;
        }
        return baseMapper.deleteById(id) > 0;
    }

    /**
     * 通过关键字搜索资源
     * @param keyword 关键字
     * @return 资源列表
     */
    public List<Resource> searchResources(String keyword) {
        return this.baseMapper.searchByKeyword(keyword);
    }
}
